package com.tuo51.wx.miniapp.controller;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import com.google.common.collect.Maps;
import com.tuo51.core.domain.staffs.Staff;
import com.tuo51.core.service.StaffService;
import com.tuo51.evaluate.vo.users.StaffVO;
import com.tuo51.foudation.constant.CommonConstant;
import com.tuo51.foudation.model.ErrorCode;
import com.tuo51.foudation.model.MemVerificationCache;
import com.tuo51.foudation.model.StatusResponse;
import com.tuo51.wx.miniapp.config.WxMaConfiguration;
import com.tuo51.wx.miniapp.config.WxMaProperties;
import com.tuo51.wx.miniapp.utils.JsonUtils;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 微信小程序用户接口
 *
 */
@RestController
@RequestMapping("/wx/user/{appid}")
public class WxMaUserController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private WxMaProperties properties;

    @Autowired
    StaffService staffService;

    @Autowired
    MemVerificationCache cache;

    @GetMapping("/login")
    public StatusResponse login(@RequestHeader(name = "clientSystem",required = false) String clientSystem,
                                @RequestHeader(name = "clientVersion",required = false) String clientVersion,
                                @RequestHeader(name = "ipAddress",required = false) String ipAddress,
                                @PathVariable String appid,
                                String code) {

        if (StringUtils.isBlank(code)) {
            return StatusResponse.error(ErrorCode.UNDEFINED,"empty jscode");
        }

        if(!validAppId(appid)){
            return StatusResponse.error(ErrorCode.UNDEFINED,"unsupported appid");
        }

        final WxMaService wxService = WxMaConfiguration.getMaService(appid);

        try {
            WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(code);
            this.logger.info(session.getSessionKey());
            this.logger.info(session.getOpenid());
            this.logger.info(session.getUnionid());

            ///
            Staff user = null;
            if( StringUtils.isNotEmpty(session.getUnionid())){
                user = staffService.getUnionID(session.getUnionid(), appid);
            }
            if(user == null){  // unionid找不到，就用openid 找
                user = staffService.getOpenIDMA(session.getOpenid(), appid);
                if (user != null && user.getTemporally()){  //取消临时账号
                    user.setTemporally(false);
                }
            }
            if (Objects.isNull(user)) {
                //String realName, String mobile, Integer gender, String areaName, String address, String areaId
                user = staffService.add(session.getOpenid(), null, session.getUnionid(), session.getSessionKey(), appid,
                        CommonConstant.Platform.WXMA);
            }else{
                user = staffService.updateSessionKey(user, session.getUnionid(), session.getSessionKey());
            }

            Map<String, Object> result = Maps.newHashMap();
            result.put("user", StaffVO.of(user, staffService.staffOrgnization(user)));

            String ticket = cache.produceTicket(user.getId(), CommonConstant.Platform.WXMA.codeOf());
            result.put("ticket", ticket);

            result.put("session", session);

            ///
            return StatusResponse.success(result);
        } catch (WxErrorException e) {
            this.logger.error(e.getMessage(), e);
            return StatusResponse.error(ErrorCode.UNDEFINED, e.getMessage());
        }
    }

    private boolean validAppId(String appid){
        List<WxMaProperties.Config> configs = this.properties.getConfigs();
        for (WxMaProperties.Config c : configs){
            if(c.getAppid().equals(appid)){
                return true;
            }
        }
        return false;
    }

    /**
     * <pre>
     * 获取用户信息接口
     * </pre>
     */
    @PostMapping("/wxinfo")
    public String info(@PathVariable String appid, String sessionKey,
                       String signature, String rawData, String encryptedData, String iv) {
        final WxMaService wxService = WxMaConfiguration.getMaService(appid);

        // 用户信息校验
        if (!wxService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
            return "user check failed";
        }

        // 解密用户信息
        WxMaUserInfo userInfo = wxService.getUserService().getUserInfo(sessionKey, encryptedData, iv);

        staffService.updateMaUserInfo(sessionKey, userInfo, appid);

        return JsonUtils.toJson(userInfo);
    }

    /**
     * <pre>
     * 获取用户绑定手机号信息
     * </pre>
     */
    @GetMapping("/wxphone")
    public StatusResponse phone(@PathVariable String appid,
                                String sessionKey,
                                String encryptedData,
                                String iv) {
        final WxMaService wxService = WxMaConfiguration.getMaService(appid);

        // 解密
        WxMaPhoneNumberInfo phoneNoInfo = wxService.getUserService().getPhoneNoInfo(sessionKey, encryptedData, iv);

        staffService.updatePhoneNumberInfo(sessionKey, phoneNoInfo.getPhoneNumber(), appid);

        return StatusResponse.success(phoneNoInfo);
    }
}
